package com.sixeco.apigetway.handle;

import java.io.FileInputStream;
import java.security.KeyStore;
import java.util.concurrent.atomic.AtomicInteger;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.sixeco.apigetway.common.CommonVar;
import com.sixeco.apigetway.controller.FormController;

import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.ssl.SslHandler;
import io.netty.handler.stream.ChunkedWriteHandler;

import com.sixeco.apigetway.common.CommonVar.HttpChunk;

/**
 * 链路初始化
 * @author tianzhenjiu
 *
 */
public class ChannelHandleInit extends ChannelInitializer<Channel>{

	
	Logger logger=LoggerFactory.getLogger(getClass());
	
	

	
	
	
	/**
	 * 创建一个SSL引擎
	 */
	public SSLEngine createSSLEngine(String pass,String jksPath) throws Exception {
		
		
		  
        SSLContext sslContext = SSLContext.getInstance("TLS");
		char[] passArray =pass.toCharArray();
	  	KeyStore ks = KeyStore.getInstance("jks");
        //加载keytool 生成的文件
        FileInputStream inputStream = new FileInputStream(jksPath);
        ks.load(inputStream,passArray );
        
        KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        kmf.init(ks, passArray);
        sslContext.init(kmf.getKeyManagers(), null, null);
        
        SSLEngine engine=sslContext.createSSLEngine();
        engine.setUseClientMode(false);
        engine.setNeedClientAuth(false);
        
		return engine;
		
	}
	
	
	
	
	@Override
	protected void initChannel(Channel ch) throws Exception {
	
		
		SSLEngine engine=null;
		
		if(CommonVar.HttpChunk.SSL_ISENABLE) {			
			try {
				
				engine=createSSLEngine(CommonVar.HttpChunk.SSL_PASSWORD, CommonVar.HttpChunk.SSL_JKSPATH);
			} catch (Exception e) {
				logger.warn("开启SSL失败",e);
			}
		}
		
		 ChannelPipeline channelPipeline=ch.pipeline();
		 
		 
		 if(engine!=null) {
			 channelPipeline.addLast(new SslHandler(engine)); 
		 }
		 
		 channelPipeline.addLast(
				 new HttpServerCodec(
						 HttpChunk.maxInitialLineLength,
						 HttpChunk.maxHeaderSize, 
						 HttpChunk.maxChunkSize));
		 
		 channelPipeline.addLast(new ChunkedWriteHandler());
		 
		 channelPipeline.addLast(new HttpObjectAggregator(
				 HttpChunk.maxChunkSize));
		 
		 channelPipeline.addLast(new AbHttpHandle(new FormController()));
		 
		 ch.attr(CommonVar.Proxy.lastRequestTime).set(0l);
		 ch.attr(CommonVar.Proxy.requstCount).set(new AtomicInteger(0));
		 
		 
	}
}
